// 类型的参数化

// 在定义这个函数时, 我不决定这些参数的类型
// 而是让调用者以参数的形式告知,我这里的函数参数应该是什么类型
// function sum(num1: ?,  num2: ?)
// function sum<Type> 当成一个额外的参数 sum<number>(20)
function sum<Type>(num: Type): Type {
	return num
}

// 1.调用方式一: 明确的传入类型
sum<number>(20)
sum<{ name: string }>({ name: 'why' }) // 传入类型是一个对象类型
sum<any[]>(['abc'])
console.log(sum<number>(20))

// 2.调用方式二: 类型推到
sum(50)
sum('abc')
console.log(sum(50), sum('abc'))
// ？：表示该属性或参数为可选项
function foo<T, E, O>(arg1: T, arg2: E, arg3?: O, ...args: T[]) {
    console.log(arg1, arg2, arg3, [...args]);
}

foo<number, string, boolean>(10, 'abc', true, 1, 2)
/**
 泛型的基本补充
 T：    Type缩写
 K、V： key和value缩写，键值对
 E：    element缩写，元素
 O：    object缩写，对象
 */

